//
//  CZPhotoBrowserCell.swift
//  GZWeibo666
//
//  Created by Apple on 15/12/7.
//  Copyright © 2015年 itcast. All rights reserved.
//

import UIKit

import SDWebImage

import SVProgressHUD

let CellMinimumZoomScale: CGFloat = 0.5

/// 自定义cell
class CZPhotoBrowserCell: UICollectionViewCell {
    
    // MARK: - 属性
    weak var delegate: CZPhotoBrowserCellDelegate?
    
    deinit {
        print("CZPhotoBrowserCell deinit")
    }
    
    /// 图片的url
    var url: NSURL? {
        didSet {
            guard let imageURL = url else {
                print("url没有值")
                return
            }
            
            // 清空图片
            imageView.image = nil
            
            // 清空被复用的参数
            scrollView.contentOffset = CGPointZero
            scrollView.contentSize = CGSizeZero
            scrollView.contentInset = UIEdgeInsetsZero
            imageView.transform = CGAffineTransformIdentity
            
            // 显示菊花
//            indicator.startAnimating()
            
            // 下载图片, sd_setImageWithURL直接设置gif图片,内存会飙升
//            imageView.sd_setImageWithURL(imageURL) { (image, error, _, _) -> Void in
//                // 隐藏菊花
//                self.indicator.stopAnimating()
//                
//                if error != nil {
//                    print("下载图片出错")
//                    return
//                }
//                
//                print("下载图片完成: \(imageURL.absoluteString)")
////                self.imageView.sizeToFit()
//                self.layoutImageView(image)
//            }
            
            // 先将图片下载到本地,在来设置
            
            // 解决循环引用
//            weak var weakSelf = self
            
            SDWebImageManager.sharedManager().downloadImageWithURL(imageURL, options: SDWebImageOptions(rawValue: 0), progress: { (a, b) -> Void in
                let progress = Float(a) / Float(b)
                // 退出照片浏览控制器时,还会显示进度
                    // 显示进度
                    // 判断代理在不在
                if self.delegate != nil {
                    dispatch_async(dispatch_get_main_queue(), { () -> Void in
                        SVProgressHUD.showProgress(progress)
                        print("要显示进度条")
                    })
                } else {
                    // 退出控制器,还在下载,退出的时候就不要去下载了。
                    // 取消所有下载
                    SDWebImageManager.sharedManager().cancelAll()
                    print("不需要显示进度条")
                    SVProgressHUD.dismiss()
                }
                }) { [weak self] (image, error, _, _, _) -> Void in
                    // [weak self] 占有列表,闭包里面的self都是weak
                    SVProgressHUD.dismiss()
                    
                    if error != nil {
                        print("下载图片失败")
                        SVProgressHUD.showErrorWithStatus("下载图片失败")
                        return
                    }
                    
                    print("下载图片成功: \(imageURL)")
                    
                    // 判断是否是gif图片
                    let isGif = imageURL.absoluteString.lowercaseString.hasSuffix("gif")
                    
                    // 不是gif正常设置图片
                    if !isGif {
                        // 设置图片
                        self?.imageView.image = image
                        
                        // 重新布局 将图片等比缩放到宽度等于屏幕的宽度
                        self?.layoutImageView(image)
                    } else {
                        // 是gif
                        // 去本地缓存查找下载好的gif图片
                        // 获取到SDWebImage保存的图片名称, 将url地址,进行MD5转换成图片的名称
                        let imageNamed = SDWebImageManager.sharedManager().cacheKeyForURL(imageURL)
                        
                        // 获得完整的图片路径
//                        let path = SDWebImageManager.sharedManager().imageCache.cachePathForKey(imageNamed, inPath: imageNamed)
                        
                        let path = SDWebImageManager.sharedManager().imageCache.defaultCachePathForKey(imageNamed)
                        print("获得完整的图片路径: \(path)")
                        // 生成gif 对应的Image
                        // 不能立马获取,需要等一会
                        dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (Int64)(250 * USEC_PER_SEC)), dispatch_get_main_queue(), { () -> Void in
                            let data = NSData(contentsOfFile: path)!
                            self?.imageView.image = UIImage.sd_animatedGIFWithData(data)
                            
                            // 重新布局 将图片等比缩放到宽度等于屏幕的宽度
                            self?.layoutImageView(self!.imageView.image!)
                        })
                    }
            }
        }
    }
    
    private func testAfterLoadImage(url: NSURL) {
        // 模拟网络延迟
        dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (Int64)(1 * NSEC_PER_SEC)), dispatch_get_main_queue()) { () -> Void in
            // 下载图片
            self.imageView.sd_setImageWithURL(url) { (image, error, _, _) -> Void in
                // 隐藏菊花
//                self.indicator.stopAnimating()
                
                if error != nil {
                    print("下载图片出错")
                    return
                }
                
                self.layoutImageView(image)
            }
        }
    }
    
    /*
        将图片等比缩放到宽度等于屏幕的宽度
            长图: 高度大于屏幕的高度
            短图: 高度小于屏幕的高度
    */
    private func layoutImageView(image: UIImage) {
        // 将图片等比缩放到宽度等于屏幕的宽度
        let size = self.displaySize(image)
        
        // 判断是长图还是短图
        // 长图:从左上角开始显示.可以滚动
        // 短图:高度方向居中显示
        if size.height < UIScreen.height() {
            // 短图:高度方向居中显示
            let offestY = (UIScreen.height() - size.height) * 0.5
            
            // 设置frame后,imageView不管怎么缩放,frame.origin.y都是不变的,缩放后不会居中显示,而且底部可能会看不到
//            imageView.frame = CGRect(origin: CGPoint(x: 0, y: offestY), size: size)
            
            imageView.frame = CGRect(origin: CGPointZero, size: size)
            scrollView.contentInset = UIEdgeInsets(top: offestY, left: 0, bottom: offestY, right: 0)
        } else {
            imageView.frame = CGRect(origin: CGPointZero, size: size)
            
            // scrollView设置contentSize
            scrollView.contentSize = size
        }
    }
    
    /// 将图片等比缩放到宽度等于屏幕的宽度
    private func displaySize(image: UIImage) -> CGSize {
        // 新的高度 / 新的宽度 = 旧的高度 / 旧的宽度
        // 新的高度 = 新的宽度(屏幕的宽度) * 旧的高度 / 旧的宽度
        let newWidth = UIScreen.width()
        let newHeight = newWidth * image.size.height / image.size.width
        
        return CGSize(width: newWidth, height: newHeight)
    }
    
    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    override init(frame: CGRect) {
        super.init(frame: frame)
        
        prepareUI()
        
        // 让cell成为collecitonView的代理
        scrollView.delegate = self
        
        // 设置最大和最小缩放比例
        scrollView.maximumZoomScale = 2
        scrollView.minimumZoomScale = CellMinimumZoomScale
    }
    
    // MARK: - 准备UI
    private func prepareUI() {
        // 添加子控件
        contentView.addSubview(scrollView)
        
        // 注意需要加到scrollView里面
        scrollView.addSubview(imageView)
        
        // 添加进来
//        contentView.addSubview(indicator)
        
        // 添加约束
        // scrollView 填充父控件
        scrollView.translatesAutoresizingMaskIntoConstraints = false
        contentView.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("H:|-0-[sv]-0-|", options: NSLayoutFormatOptions(rawValue: 0), metrics: nil, views: ["sv": scrollView]))
        contentView.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("V:|-0-[sv]-0-|", options: NSLayoutFormatOptions(rawValue: 0), metrics: nil, views: ["sv": scrollView]))
        
        // 菊花
//        indicator.translatesAutoresizingMaskIntoConstraints = false
//        contentView.addConstraint(NSLayoutConstraint(item: indicator, attribute: NSLayoutAttribute.CenterX, relatedBy: NSLayoutRelation.Equal, toItem: contentView, attribute: NSLayoutAttribute.CenterX, multiplier: 1, constant: 0))
//        contentView.addConstraint(NSLayoutConstraint(item: indicator, attribute: NSLayoutAttribute.CenterY, relatedBy: NSLayoutRelation.Equal, toItem: contentView, attribute: NSLayoutAttribute.CenterY, multiplier: 1, constant: 0))
    }
    
    // MARK: - 懒加载
    /// scrollView
    private lazy var scrollView = UIScrollView()
    
    /// imageView
    lazy var imageView: CZImageView = CZImageView()
    
    /// 加载菊花
//    private lazy var indicator = UIActivityIndicatorView(activityIndicatorStyle: UIActivityIndicatorViewStyle.WhiteLarge)
}

protocol CZPhotoBrowserCellDelegate: NSObjectProtocol {
    /// 返回一个view设置背景
    func viewForTransparent() -> UIView
    
    /// 关闭控制器
    func photoBrowserCellDismissController()
    
    /// 返回大图缩放到小图的位置
    func photoBrowserCellDismissTargetRect() -> CGRect
}

// MARK: - 扩展 CZPhotoBrowserCell 实现 UIScrollViewDelegate
extension CZPhotoBrowserCell: UIScrollViewDelegate {
    /// 告诉scrollView要缩放哪个view(缩放其实是修改这个view的transform)
    func viewForZoomingInScrollView(scrollView: UIScrollView) -> UIView? {
        return imageView
    }
    
    /// 当图片缩放比例小于最小缩放比例松手时,不会立马调用scrollViewDidEndZooming,回先自动缩放到最小缩放比例
    /// 不让系统缩放到比设置的缩放比例还小的值
    /// 每当我们缩放一点点都会来调用
    func scrollViewDidZoom(scrollView: UIScrollView) {
        // 让控制器给返回一个view我们来设置alpha值,实时改变控制器的背景
        let bkgView = delegate?.viewForTransparent()
        
        // 缩放比例小于1,设置透明的
        if imageView.transform.a < 1 {
            bkgView?.alpha = imageView.transform.a * 0.7 - 0.1
        } else {
            // 缩放比例大于1,设置alpha为1
            bkgView?.alpha = 1
        }
    }
    
    /// 缩放结束的时候调用
    /// 注意.建议使用frame, frame在缩放的时候是一直变化的, bounds在缩放的时候是一直不变的
    func scrollViewDidEndZooming(scrollView: UIScrollView, withView view: UIView?, atScale scale: CGFloat) {
        print("scrollViewDidEndZooming---------\(imageView.transform)")
        
        // 监听imageView的缩放,是否到了可以关闭控制器的状态
        if imageView.transform.a < 0.7 {
            // 关闭控制器,cell不能关闭控制器,通过代理,告诉控制器现在可以关闭了
            // 不能直接这样关闭,直接关闭,转场动画时拿到的imageView的frame和显示的是不一样的,会先跳到左上角在转场动画到指定位置
//            delegate?.photoBrowserCellDismissController()
            
            
            // 移动到缩略图的位置
            if let rect = delegate?.photoBrowserCellDismissTargetRect() {
//                print("rect:\(rect)")
                
                // 设置imageView的模型
                imageView.contentMode = UIViewContentMode.ScaleAspectFill
                imageView.clipsToBounds = true
                
                // 动画
//                self.imageView.transform = CGAffineTransformIdentity
                UIView.animateWithDuration(0.25, animations: { () -> Void in
                    self.imageView.frame = CGRect(origin: CGPointZero, size: rect.size)
                    scrollView.contentInset = UIEdgeInsets(top: rect.origin.y, left: rect.origin.x, bottom: 0, right: 0)
                    
                    // 设置contentOffest.y,长图时y值对不上.发现contentOffestY有问题
                    scrollView.contentOffset.y = -rect.origin.y
                    scrollView.contentOffset.x = -rect.origin.x
                    }, completion: { (_) -> Void in
                        // 关闭控制器
                        delegate?.photoBrowserCellDismissController()
                })
                
            }
            
            return
        } else {
            // 移动到中间
            var offestX = (UIScreen.width() - imageView.frame.size.width) * 0.5
            var offestY = (UIScreen.height() - imageView.frame.size.height) * 0.5
            
            // 当 offestX,offestY小于0回到屏幕外面去。
            if offestX < 0 {
                offestX = 0
            }
            
            if offestY < 0 {
                offestY = 0
            }
            
            // 动画
            UIView.animateWithDuration(0.25) { () -> Void in
                // 通过scrollView ContentInset
                scrollView.contentInset = UIEdgeInsets(top: offestY, left: offestX, bottom: 0, right: 0)
            }
        }
    }
}
